In [18]:
from google.colab import files
uploaded = files.upload()
Saving GlobalLandTemperaturesByCountry.csv to GlobalLandTemperaturesByCountry (1).csv
In [45]:
"""
Segmentation non supervisée par clustering (KMeans)
---------------------------------------------------
Auteur : CISSE Ibrahim
Ce notebook présente une méthode clé en ananlyse de données : le clustering non supervisé, utilisé pour segmenter des données sans étiquettes préalables.
L’objectif est d’identifier des groupes homogènes dans une population, à partir de variables numériques.
Nous utilisons ici l’algorithme KMeans, reconnu pour sa simplicité et son efficacité sur des données bien séparables. Le notebook est structuré pour :
- Préparer et standardiser les données
- Appliquer le clustering
- Visualiser les groupes obtenus
- Évaluer la cohérence des clusters
Jeu de données utilisé :
Source : https://www.kaggle.com/datasets/berkeleyearth/climate-change-earth-surface-temperature-data
Fichier : GlobalLandTemperaturesByCountry.csv
Colonnes :
dt : date
AverageTemperature
AverageTemperatureUncertainty
Country
"""
Out[45]:
'\nSegmentation non supervisée par clustering (KMeans)\n---------------------------------------------------\nAuteur : CISSE Ibrahim\n\nCe notebook présente une méthode clé en ananlyse de données : le clustering non supervisé, utilisé pour segmenter des données sans étiquettes préalables.\nL’objectif est d’identifier des groupes homogènes dans une population, à partir de variables numériques.\n\nNous utilisons ici l’algorithme KMeans, reconnu pour sa simplicité et son efficacité sur des données bien séparables. Le notebook est structuré pour :\n- Préparer et standardiser les données\n- Appliquer le clustering\n- Visualiser les groupes obtenus\n- Évaluer la cohérence des clusters\n\n Jeu de données utilisé :\n Source : https://www.kaggle.com/datasets/berkeleyearth/climate-change-earth-surface-temperature-data\n Fichier : GlobalLandTemperaturesByCountry.csv\n Colonnes :\n dt : date\n AverageTemperature\n AverageTemperatureUncertainty\n Country\n\n'
In [41]:
# Chargement des toutes les bibliothèques utiles
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import plotly.express as px
print("Toutes les bibliothques utiles ont bien été chargées")
Toutes les bibliothques utiles ont bien été chargées
In [19]:
# Chargement et structuration des données
#Chargement
df = pd.read_csv("GlobalLandTemperaturesByCountry.csv")
# Conversion de la colonne 'dt' en datetime
df["dt"] = pd.to_datetime(df["dt"])
# Filtrage des années entre 1960 et 2020
df = df[(df["dt"].dt.year >= 1960) & (df["dt"].dt.year <= 2020)]
# Suppression des lignes avec température manquante
df = df.dropna(subset=["AverageTemperature"])
# Suppression des entrées sans pays ('Antarctica' ou valeurs nulles)
df = df[df["Country"].notna() & (df["Country"] != "Antarctica")]
# Vérification du résultat
df.shape, df["Country"].nunique(), df["dt"].dt.year.min(), df["dt"].dt.year.max()
df.head()
Out[19]:
| dt | AverageTemperature | AverageTemperatureUncertainty | Country | |
|---|---|---|---|---|
| 2594 | 1960-01-01 | -4.380 | 0.430 | Åland |
| 2595 | 1960-02-01 | -5.233 | 0.382 | Åland |
| 2596 | 1960-03-01 | -2.362 | 0.638 | Åland |
| 2597 | 1960-04-01 | 1.922 | 0.450 | Åland |
| 2598 | 1960-05-01 | 8.495 | 0.287 | Åland |
In [20]:
# Agrégaqtion annuelle par pays.
# Ajout d'une colonne 'Année'
df["Année"] = df["dt"].dt.year
# Calcul de la moyenne annuelle par pays
df_agg = df.groupby(["Country", "Année"])["AverageTemperature"].mean().reset_index()
# Pivot : chaque pays devient une ligne, chaque année une colonne
df_pivot = df_agg.pivot(index="Country", columns="Année", values="AverageTemperature")
# Suppression des pays avec trop de valeurs manquantes
df_pivot = df_pivot.dropna(thresh=50) # au moins 50 années présentes
# Vérification
df_pivot.shape
Out[20]:
(242, 54)
In [21]:
# Standardisation et clustering
# Standardisation des températures par pays
X = df_pivot.fillna(method="ffill", axis=1).fillna(method="bfill", axis=1) # interpolation simple
X_std = (X - X.mean()) / X.std()
# Application de KMeans avec 3 clusters
kmeans = KMeans(n_clusters=3, init="k-means++", n_init=10, random_state=42)
labels = kmeans.fit_predict(X_std)
# Ajout des labels au DataFrame
X["cluster"] = labels
# Aperçu des affectations
X["cluster"].value_counts().sort_index()
/tmp/ipython-input-3979938624.py:4: FutureWarning: DataFrame.fillna with 'method' is deprecated and will raise in a future version. Use obj.ffill() or obj.bfill() instead. X = df_pivot.fillna(method="ffill", axis=1).fillna(method="bfill", axis=1) # interpolation simple
Out[21]:
| count | |
|---|---|
| cluster | |
| 0 | 158 |
| 1 | 13 |
| 2 | 71 |
In [31]:
# visualisation des clusters (ex. PCA + scatter plot)
# Exemple fictif : données standardisées X_std, labels de cluster, noms de pays
# En pratique, ces variables doivent être déjà calculées
# Ici, on crée des données simulées pour démonstration
np.random.seed(42)
X_std = np.random.randn(50, 6) # 50 pays, 6 variables climatiques
labels = np.random.randint(0, 3, size=50) # 4 clusters
pays = [f"Pays_{i}" for i in range(50)]
# Réduction de dimension par ACP (PCA)
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_std)
# Création du DataFrame pour visualisation
df_plot = pd.DataFrame({
"PC1": X_pca[:, 0],
"PC2": X_pca[:, 1],
"Cluster": labels,
"Pays": pays
})
# Visualisation scatter plot 2D
plt.style.use("seaborn-v0_8")
plt.figure(figsize=(10, 7))
for cluster_id in sorted(df_plot.Cluster.unique()):
subset = df_plot[df_plot.Cluster == cluster_id]
plt.scatter(subset["PC1"], subset["PC2"], label=f"Cluster {cluster_id}", s=60)
# Annotation des axes et titre
plt.xlabel("Composante principale 1")
plt.ylabel("Composante principale 2")
plt.title("Clusters climatiques des pays (ACP + KMeans)")
plt.legend()
plt.grid(True)
plt.tight_layout()
# Extraction des températures en 1960 et 2020
df_plot = X.copy()
df_plot["temp_1960"] = df_pivot[1960]
df_plot["temp_2013"] = df_pivot[2013]
# Scatter plot : température 1960 vs 2020, coloré par cluster
plt.figure(figsize=(8, 6))
for i in sorted(df_plot["cluster"].unique()):
subset = df_plot[df_plot["cluster"] == i]
plt.scatter(subset["temp_1960"], subset["temp_2013"], label=f"Cluster {i}", alpha=0.7)
plt.xlabel("Température moyenne en 1960 (°C)")
plt.ylabel("Température moyenne en 2013 (°C)")
plt.title("Clustering climatique des pays (1960 vs 2020)")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
In [39]:
# Interpretation des clusters
# Reconstruction du DataFrame utilisé pour le clustering
X_std_df = pd.DataFrame(X_std, columns=df_pivot.columns[:X_std.shape[1]])
# Ajout des labels
X_std_df["cluster"] = labels
# Calcul de la moyenne par cluster
df_cluster_mean = X_std_df.groupby("cluster").mean()
# Visualisation
df_cluster_mean.T.plot(figsize=(10, 6), cmap="tab10")
plt.title("Évolution thermique moyenne par cluster (années utilisées)")
plt.xlabel("Année")
plt.ylabel("Température moyenne (°C)")
plt.grid(True)
plt.tight_layout()
plt.show()
In [44]:
# Création du DataFrame des pays utilisés dans le clustering
countries_used = df_pivot.dropna().index[:len(labels)] # longueur = len(labels) = 50
# Création du DataFrame des clusters
df_map = pd.DataFrame({
"country": countries_used,
"cluster": labels
})
# Attribution des noms
cluster_names = {0: "Tempéré", 1: "Chaud", 2: "Froid"}
df_map["cluster_name"] = df_map["cluster"].map(cluster_names)
# Carte choroplèthe
fig = px.choropleth(
df_map,
locations="country",
locationmode="country names",
color="cluster_name",
title="Répartition géographique des clusters climatiques",
color_discrete_map={
"Froid": "#1f77b4",
"Tempéré": "#ff7f0e",
"Chaud": "#2ca02c"
}
)
fig.update_layout(margin={"r":0,"t":40,"l":0,"b":0})
fig.show()
In [ ]:
## Clustering climatique des pays (1960–2013) — Synthèse finale
### Données
- Source : températures annuelles moyennes par pays
- Période analysée : 1960 à 2013
- Format pivoté : pays × années
### Prétraitement
- Filtrage des pays avec données complètes
- Standardisation des températures par colonne
### Clustering
- Méthode : KMeans (n_clusters = 3)
- Espace utilisé : températures standardisées sur 6 années
- Résultat : 3 groupes climatiques cohérents
### Interprétation
- Cluster 1 → **Chaud** : températures élevées et stables
- Cluster 0 → **Tempéré** : profil intermédiaire, stable
- Cluster 2 → **Froid** : températures basses, forte variabilité
### Cartographie
- Visualisation interactive par pays
- Couleurs : bleu (froid), orange (tempéré), vert (chaud)
### Finalité
- Méthode démonstrative et reproductible
- Nommage des clusters basé sur les profils thermiques moyens
- Visualisation claire des dynamiques climatiques par groupe
## Études complémentaires possibles
### Analyse de trajectoires climatiques
- Détection des accélérations ou ruptures climatiques
- Segmentation selon la vitesse de dérive
### Fusion avec d'autres données
- **Agriculture** : dépendance aux cultures sensibles → vulnérabilité alimentaire
- **Émissions CO₂** : croisement avec responsabilité climatique
- **Énergie** : part des renouvelables, dépendance thermique
### Applications stratégiques
- Identification des pays à **fort risque climatique**
- Priorisation des zones pour **adaptation ou financement**
- Aide à la **planification territoriale** ou aux politiques environnementales
- Base pour des **dashboards décisionnels** ou des alertes automatisées